package com.kadron.paging;

import java.util.List;

import javax.persistence.Query;

import com.kadron.dao.KCommonDAO;
import com.kadron.datamodel.KModel;
import com.kadron.datamodel.KModelCreator;

public abstract class AbstractRowService implements KRowService {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5862117516679924629L;
	
	private KModelCreator creator;
	private Class<? extends KRow> clazz;
	private KCommonDAO commonDAO;;
	
	public AbstractRowService(KModelCreator creator, Class<? extends KRow> clazz, KCommonDAO commonDAO) {
		super();
		this.creator = creator;
		this.clazz = clazz;
		this.commonDAO = commonDAO;
	}

	@SuppressWarnings("unchecked")
	public void getModels(KRowParent parent, int first, int max) {
		Query query = createQuery(false);
		query.setFirstResult(first);
		query.setMaxResults(max);
		List<Long> itemIds = query.getResultList();
		doCreate(parent, itemIds);
	}

	public KRow getItemById(Long id) {
		return creator.create(id);
	}

	public long getCount(KRowParent parent) {
		Query query = createQuery(true);
		Long countNumber = (Long) query.getSingleResult();
		long count = (countNumber == null) ? 0 : countNumber.intValue();
		parent.getModelContainer().setCount(count);
		return  count;
	}

	public boolean hasItemWithId(Long id) {
		return commonDAO.exists(id, clazz);
	}

	public KModelCreator getCreator() {
		return creator;
	}
	
	public abstract void getAllModels(KRowParent parent);

	public KRowParent doCreate(KRowParent parent, List<Long> rows) {
		parent.getModelContainer().getModels().clear();
		for (Long rowId : rows) {
			KRow model = null;
			String key = rowId.toString();
			if (!parent.getModelContainer().getWrappedKeys().contains(key)) {
				model = creator.create(rowId);
			} else {
				model = (KModel) parent.getModelContainer().getWrappedData().get(key);
			}
			parent.getModelContainer().getModels().add(model);
			parent.getModelContainer().wrapp(key, model);
		}
		parent.getModelContainer().initPages();
		return parent;
	}
	
	public KCommonDAO getCommonDAO() {
		return commonDAO;
	}
	
	public abstract Query createQuery(boolean isCount);

}
